[IA64] Performance enhancement for big-endian, 4k-pages, protection keys
authorAlex Williamson <alex.williamson@hp.com>
Mon, 17 Sep 2007 19:26:19 +0000 (13:26 -0600)
committerAlex Williamson <alex.williamson@hp.com>
Mon, 17 Sep 2007 19:26:19 +0000 (13:26 -0600)
Signed-off-by: Juergen Gross <juergen.gross@fujitsu-siemens.com>
xen/arch/ia64/xen/faults.c
xen/arch/ia64/xen/hyperprivop.S
xen/arch/ia64/xen/ivt.S
xen/arch/ia64/xen/mm.c
xen/arch/ia64/xen/vcpu.c
xen/arch/ia64/xen/vhpt.c

index f201d3fe564273c49bafca7b8cb29d6da5fef366..6ab41dd2611e653cc0d71c83c765543f7db9e063 100644 (file)
@@ -602,6 +602,9 @@ ia64_handle_reflection(unsigned long ifa, struct pt_regs *regs,
                check_lazy_cover = 1;
                vector = IA64_PAGE_NOT_PRESENT_VECTOR;
                break;
+       case 21:
+               vector = IA64_KEY_PERMISSION_VECTOR;
+               break;
        case 22:
                vector = IA64_INST_ACCESS_RIGHTS_VECTOR;
                break;
index 52658f29fa3df4d4ebea990e02ee613605d66eec..f78e8a70e6756de6ef8549430d1bb4d84e656ce4 100644 (file)
@@ -223,9 +223,6 @@ ENTRY(hyper_ssm_i)
        // give up for now if: ipsr.be==1, ipsr.pp==1
        mov r30=cr.ipsr
        mov r29=cr.iip;;
-       extr.u r21=r30,IA64_PSR_BE_BIT,1 ;;
-       cmp.ne p7,p0=r21,r0
-(p7)   br.sptk.many dispatch_break_fault ;;
        extr.u r21=r30,IA64_PSR_PP_BIT,1 ;;
        cmp.ne p7,p0=r21,r0
 (p7)   br.sptk.many dispatch_break_fault ;;
@@ -268,7 +265,7 @@ ENTRY(hyper_ssm_i)
        // FOR SSM_I ONLY, also turn on psr.i and psr.ic
        movl r28=(IA64_PSR_DT|IA64_PSR_IT|IA64_PSR_RT|IA64_PSR_I|IA64_PSR_IC)
 //     movl r27=~(IA64_PSR_BE|IA64_PSR_PP|IA64_PSR_BN);;
-       movl r27=~(IA64_PSR_BE|IA64_PSR_BN);;
+       movl r27=~IA64_PSR_BN;;
        or r30=r30,r28;;
        and r30=r30,r27;;
        mov r20=1
@@ -361,10 +358,7 @@ GLOBAL_ENTRY(fast_tick_reflect)
        cmp.ltu p6,p0=r26,r27
 (p6)   br.cond.spnt.few rp;;
        mov r17=cr.ipsr;;
-       // slow path if: ipsr.be==1, ipsr.pp==1
-       extr.u r21=r17,IA64_PSR_BE_BIT,1 ;;
-       cmp.ne p6,p0=r21,r0
-(p6)   br.cond.spnt.few rp;;
+       // slow path if: ipsr.pp==1
        extr.u r21=r17,IA64_PSR_PP_BIT,1 ;;
        cmp.ne p6,p0=r21,r0
 (p6)   br.cond.spnt.few rp;;
@@ -453,7 +447,7 @@ GLOBAL_ENTRY(fast_tick_reflect)
        cmp.eq p7,p0=CONFIG_CPL0_EMUL,r29;;
 (p7)   dep r17=0,r17,IA64_PSR_CPL0_BIT,2
        movl r28=(IA64_PSR_DT|IA64_PSR_IT|IA64_PSR_RT)
-       movl r27=~(IA64_PSR_BE|IA64_PSR_PP|IA64_PSR_BN|IA64_PSR_I|IA64_PSR_IC);;
+       movl r27=~(IA64_PSR_PP|IA64_PSR_BN|IA64_PSR_I|IA64_PSR_IC);;
        or r17=r17,r28;;
        and r17=r17,r27
        ld4 r16=[r18];;
@@ -556,9 +550,6 @@ GLOBAL_ENTRY(fast_break_reflect)
 #endif
        mov r30=cr.ipsr
        mov r29=cr.iip;;
-       extr.u r21=r30,IA64_PSR_BE_BIT,1 ;;
-       cmp.ne p7,p0=r21,r0
-(p7)   br.spnt.few dispatch_break_fault ;;
        extr.u r21=r30,IA64_PSR_PP_BIT,1 ;;
        cmp.ne p7,p0=r21,r0
 (p7)   br.spnt.few dispatch_break_fault ;;
@@ -633,7 +624,7 @@ ENTRY(fast_reflect)
        cmp.eq p7,p0=CONFIG_CPL0_EMUL,r29;;
 (p7)   dep r30=0,r30,IA64_PSR_CPL0_BIT,2
        movl r28=(IA64_PSR_DT|IA64_PSR_IT|IA64_PSR_RT)
-       movl r27=~(IA64_PSR_BE|IA64_PSR_PP|IA64_PSR_BN);;
+       movl r27=~(IA64_PSR_PP|IA64_PSR_BN);;
        or r30=r30,r28;;
        and r30=r30,r27
        // also set shared_mem ipsr.i and ipsr.ic appropriately
@@ -744,9 +735,6 @@ GLOBAL_ENTRY(fast_access_reflect)
 #endif
        mov r30=cr.ipsr
        mov r29=cr.iip;;
-       extr.u r21=r30,IA64_PSR_BE_BIT,1 ;;
-       cmp.ne p7,p0=r21,r0
-(p7)   br.spnt.few dispatch_reflection ;;
        extr.u r21=r30,IA64_PSR_PP_BIT,1 ;;
        cmp.ne p7,p0=r21,r0
 (p7)   br.spnt.few dispatch_reflection ;;
@@ -794,9 +782,6 @@ GLOBAL_ENTRY(fast_tlb_miss_reflect)
        cmp.eq p7,p0=r21,r0
 (p7)   br.spnt.few page_fault ;;
        // slow path if strange ipsr or isr bits set
-       extr.u r21=r30,IA64_PSR_BE_BIT,1 ;;
-       cmp.ne p7,p0=r21,r0
-(p7)   br.spnt.few page_fault ;;
        extr.u r21=r30,IA64_PSR_PP_BIT,1 ;;
        cmp.ne p7,p0=r21,r0
 (p7)   br.spnt.few page_fault ;;
@@ -1068,10 +1053,6 @@ ENTRY(hyper_rfi)
 1:
        adds r20=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
        ld8 r21=[r20];;         // r21 = vcr.ipsr
-       extr.u r22=r21,IA64_PSR_BE_BIT,1 ;;
-       // if turning on psr.be, give up for now and do it the slow way
-       cmp.ne p7,p0=r22,r0
-(p7)   br.spnt.few slow_vcpu_rfi ;;
        // if (!(vpsr.dt && vpsr.rt && vpsr.it)), do it the slow way
        movl r20=(IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_IT);;
        and r22=r20,r21
index e76a5af1e28c63b48561b882c561eeb6287d164e..a02125001717a874f34dba3c4da0a4ce008d7f10 100644 (file)
@@ -313,7 +313,6 @@ GLOBAL_ENTRY(dispatch_reflection)
        adds out1=16,sp
        mov out2=cr.isr
        mov out3=cr.iim
-//     mov out3=cr.itir                // TODO: why commented out?
 
        ssm psr.ic | PSR_DEFAULT_BITS
        ;;
index cccc9329a15fa69ffea555546baeeb9a7796ffae..041090c446b685f5550bcce4861636e3fd502853 100644 (file)
@@ -509,25 +509,22 @@ u64 translate_domain_pte(u64 pteval, u64 address, u64 itir__, u64* itir,
        u64 arflags;
        u64 arflags2;
        u64 maflags2;
-       u64 ps;
 
        pteval &= ((1UL << 53) - 1);// ignore [63:53] bits
 
        // FIXME address had better be pre-validated on insert
        mask = ~itir_mask(_itir.itir);
        mpaddr = ((pteval & _PAGE_PPN_MASK) & ~mask) | (address & mask);
-       ps = current->arch.vhpt_pg_shift ? current->arch.vhpt_pg_shift :
-                                          PAGE_SHIFT;
 
-       if (_itir.ps > ps)
-               _itir.ps = ps;
+       if (_itir.ps > PAGE_SHIFT)
+               _itir.ps = PAGE_SHIFT;
 
        ((ia64_itir_t*)itir)->itir = _itir.itir;/* Copy the whole register. */
        ((ia64_itir_t*)itir)->ps = _itir.ps;    /* Overwrite ps part! */
 
        pteval2 = lookup_domain_mpa(d, mpaddr, entry);
-       if (ps < PAGE_SHIFT)
-               pteval2 |= mpaddr & (PAGE_SIZE - 1) & ~((1L << ps) - 1);
+       if (_itir.ps < PAGE_SHIFT)
+               pteval2 |= mpaddr & (PAGE_SIZE - 1) & ~((1L << _itir.ps) - 1);
 
        /* Check access rights.  */
        arflags  = pteval  & _PAGE_AR_MASK;
index 83835efdfdffe2fad1f19e962395dbd1edbe311e..a95e2117e860500608962efea5cebad74386684a 100644 (file)
@@ -2319,8 +2319,6 @@ vcpu_itc_no_srlz(VCPU * vcpu, u64 IorD, u64 vaddr, u64 pte,
 {
        ia64_itir_t _itir = {.itir = itir};
        unsigned long psr;
-       unsigned long ps = (vcpu->domain == dom0) ? _itir.ps :
-                                                   vcpu->arch.vhpt_pg_shift;
 
        check_xen_space_overlap("itc", vaddr, 1UL << _itir.ps);
 
@@ -2329,12 +2327,12 @@ vcpu_itc_no_srlz(VCPU * vcpu, u64 IorD, u64 vaddr, u64 pte,
                panic_domain(NULL, "vcpu_itc_no_srlz: domain trying to use "
                             "smaller page size!\n");
 
-       BUG_ON(_itir.ps > vcpu->arch.vhpt_pg_shift);
+       BUG_ON(_itir.ps > PAGE_SHIFT);
        vcpu_tlb_track_insert_or_dirty(vcpu, vaddr, entry);
        psr = ia64_clear_ic();
        pte &= ~(_PAGE_RV2 | _PAGE_RV1);        // Mask out the reserved bits.
                                        // FIXME: look for bigger mappings
-       ia64_itc(IorD, vaddr, pte, IA64_ITIR_PS_KEY(ps, _itir.key));
+       ia64_itc(IorD, vaddr, pte, _itir.itir);
        ia64_set_psr(psr);
        // ia64_srlz_i(); // no srls req'd, will rfi later
        if (vcpu->domain == dom0 && ((vaddr >> 61) == 7)) {
@@ -2350,7 +2348,6 @@ vcpu_itc_no_srlz(VCPU * vcpu, u64 IorD, u64 vaddr, u64 pte,
        // even if domain pagesize is larger than PAGE_SIZE, just put
        // PAGE_SIZE mapping in the vhpt for now, else purging is complicated
        else {
-               _itir.ps = vcpu->arch.vhpt_pg_shift;
                vhpt_insert(vaddr, pte, _itir.itir);
        }
 }
index 16d188c2f4e34db57f4be86d9a9607bfeca1a27c..615f81b9aba63d78f863f57987c66e68839593b9 100644 (file)
@@ -293,15 +293,18 @@ __flush_vhpt_range(unsigned long vhpt_maddr, u64 vadr, u64 addr_range)
 {
        void *vhpt_base = __va(vhpt_maddr);
        u64 pgsz = 1L << current->arch.vhpt_pg_shift;
+       u64 purge_addr = vadr & ~(PAGE_SIZE - 1);
 
+       addr_range += vadr - purge_addr;
+       addr_range = (addr_range + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
        while ((long)addr_range > 0) {
                /* Get the VHPT entry.  */
-               unsigned int off = ia64_thash(vadr) -
+               unsigned int off = ia64_thash(purge_addr) -
                        __va_ul(vcpu_vhpt_maddr(current));
                struct vhpt_lf_entry *v = vhpt_base + off;
                v->ti_tag = INVALID_TI_TAG;
                addr_range -= pgsz;
-               vadr += pgsz;
+               purge_addr += pgsz;
        }
 }